package com.hyny.framework.platform.system.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.hyny.framework.platform.system.annotation.Log;
import com.hyny.framework.platform.system.entity.param.MenuParam;
import com.hyny.framework.platform.system.entity.pojo.SysMenu;
import com.hyny.framework.platform.system.entity.vo.MenuListVO;
import com.hyny.framework.platform.system.entity.vo.MenuVO;
import com.hyny.framework.platform.system.enums.MenuTypeEnum;
import com.hyny.framework.platform.system.service.ILoginService;
import com.hyny.framework.platform.system.service.SysMenuService;
import com.hyny.framework.platform.system.utils.bean.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜单表(SysMenu)表控制层
 *
 * @author 张崇阳
 * @since 2024-02-26 08:58:17
 */
@Api(tags = "菜单管理")
@ApiSupport(order = 2)
@RestController
@RequestMapping("/sysMenu")
@Slf4j
public class SysMenuController {
    /**
     * 服务对象
     */
    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private ILoginService iLoginService;

    @Log(value = "查询菜单列表")
    @ApiOperation(value = "查询菜单列表")
    @GetMapping("/list")
    @ApiOperationSupport(order = 1)
    public Result<List<MenuListVO>> menuList() {
        LambdaQueryWrapper<SysMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByAsc(SysMenu::getSort);
        lambdaQueryWrapper.orderByAsc(SysMenu::getCreatedTime);
        //获取全部菜单列表
        List<SysMenu> menus = sysMenuService.list(lambdaQueryWrapper);
        //过滤出目录
        List<SysMenu> directoryMenus =menus.stream().filter(menu-> menu.getMenuType()== MenuTypeEnum.DIRECTORY).collect(Collectors.toList());
        //将po转为vo
        List<MenuListVO> directoryVoList=  BeanUtil.copyToList(directoryMenus, MenuListVO.class);
        List<MenuListVO> menusVoList=  BeanUtil.copyToList(menus, MenuListVO.class);

        //遍历目录信息
        for (MenuListVO sysMenu:directoryVoList
        ) {
            //添加目录子集
            sysMenu.setChildMenuListVOS(recursionMenuList(sysMenu,menusVoList));
        }
        return Result.ok(directoryVoList);
    }

    @Log(value = "查询菜单信息")
    @ApiOperation(value = "查询菜单信息")
    @GetMapping("/info/{id}")
    @ApiOperationSupport(order = 2)
    public Result<MenuVO> menuInfo(@ApiParam(value = "菜单主键", required = true) @PathVariable("id") String id) {
        MenuVO menuVO=BeanUtil.copyProperties(sysMenuService.getById(id),MenuVO.class);
        return Result.ok(menuVO);
    }

    @Log(value = "添加菜单",persisted = true)
    @ApiOperation(value = "添加菜单")
    @ApiOperationSupport(order = 3)
    @PostMapping("/add")
    public Result menuAdd(@RequestBody MenuParam menuParam) {

        SysMenu pMenu=null;
        if(StrUtil.isNotBlank(menuParam.getParentId())){
            LambdaQueryWrapper<SysMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();

            switch (menuParam.getMenuType()) {
                case DIRECTORY:
                    break;
                case MENU:
                    lambdaQueryWrapper.eq(SysMenu::getMenuType, MenuTypeEnum.DIRECTORY);
                    break;
                case BUTTON:
                    lambdaQueryWrapper.eq(SysMenu::getMenuType, MenuTypeEnum.MENU);
                    break;
            }

            lambdaQueryWrapper.eq(SysMenu::getId, menuParam.getParentId());
            pMenu = sysMenuService.getOne(lambdaQueryWrapper);
        }


        if (ObjectUtil.isNull(pMenu)&&StrUtil.isNotBlank(menuParam.getParentId())) {
            return Result.error("未获取到父级信息");
        }
        //参数转换成菜单对象
        SysMenu sysMenu = BeanUtil.copyProperties(menuParam, SysMenu.class);
        sysMenuService.save(sysMenu);
        return Result.ok();
    }


    @Log(value = "修改菜单",persisted = true)
    @ApiOperation(value = "修改菜单")
    @ApiOperationSupport(order =4)
    @PutMapping("/put/{id}")
    public Result menuUpdate(@ApiParam(value = "菜单主键", required = true) @PathVariable("id") String id, @RequestBody MenuParam menuParam) {
        SysMenu sysMenu = BeanUtil.copyProperties(menuParam, SysMenu.class);
        sysMenuService.update(sysMenu,new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getId,id));
        iLoginService.logoutMenu(sysMenu.getId());
        return Result.ok();
    }

    @Log(value = "删除菜单",persisted = true)
    @ApiOperation(value = "删除菜单")
    @ApiOperationSupport(order = 5)
    @DeleteMapping("/delete/{id}")
    public Result menuDelete(@ApiParam(value = "菜单主键", required = true) @PathVariable("id") String id

    ) {
        sysMenuService.removeById(id);
        iLoginService.logoutMenu(Long.valueOf(id));
        return Result.ok();
    }

    /**
     * 递归遍历菜单信息
     * @param menuListVO 当前菜单信息
     * @param allMenus 要遍历的全部菜单信息
     * @return
     */
    public List<MenuListVO> recursionMenuList(MenuListVO menuListVO, List<MenuListVO> allMenus) {
        if(allMenus!=null&&allMenus.size()>0){
            //子菜单
            List<MenuListVO> childMenus=null;
            switch (menuListVO.getMenuType()){
                case DIRECTORY:
                    childMenus= allMenus.stream().filter(menu-> menu.getMenuType()== MenuTypeEnum.MENU&&menu.getParentId().toString().equals(menuListVO.getId())).collect(Collectors.toList());
                    break;
                case MENU:
                    childMenus= allMenus.stream().filter(menu-> menu.getMenuType()== MenuTypeEnum.BUTTON&&menu.getParentId().toString().equals(menuListVO.getId())).collect(Collectors.toList());
                    break;
            }
            if(childMenus!=null&&childMenus.size()>0){
                //遍历子节点
                for (MenuListVO menuList:childMenus) {
                    menuList.setChildMenuListVOS(recursionMenuList( menuList,  allMenus));
                }
            }
            return  childMenus;
        }else{
            return null;
        }
    }
}

